home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d18
/
exemod.arc
/
EXEMOD.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-04-28
|
5KB
|
183 lines
{
EXEMOD.PAS - Modify global variables in EXE file
Kevin Dean
16 Kellythorne Drive
DOn Mills, Ontario
Canada M3A 2L4
March 27, 1990
Modifies global variables (typed constants) in initialized data segment of EXE
files. Cannot modify global variables that are declared but not initialized
(i.e. global variables that are not typed constants) as these lie in the BSS
segment of the program and are not in fact in the EXE image file itself.
Copyright (c) 1990 by Kevin Dean
For Turbo Pascal versions 5.0 and above. This code is public domain.
}
{$B-,O+,R-,I-}
unit EXEMod;
interface
uses
DOS;
type
EXEHeader =
record
ID : word; { EXE file id }
ByteMod : word; { Load module image size mod 512 }
Pages : word; { File size (including header) div 512 }
RelocItems : word; { Number of relocation table items }
Size : word; { Header size in 16-byte paragraphs }
MinParagraphs : word; { Minimum number of paragraphs above program }
MaxParagraphs : word; { Maximum number of paragraphs above program }
StackSeg : word; { Displacement of stack segment }
SPReg : word; { Initial SP register value }
CheckSum : integer; { Word checksum - negative sum (not used) }
IPReg : word; { Initial IP register value }
CodeSeg : word; { Displacement of code segment }
FirstReloc : word; { First relocation item }
OvlN : word { Overlay number }
end;
const
EXEHSize =
sizeof(EXEHeader);
EXEID = { EXE file signature }
$5A4D;
function EXEModify(ProgName : PathStr; KeepDT : boolean; var Data; N : word) : integer;
implementation
{***}
{
Name EXEModify
Function Modifies static data in EXE files.
Declaration EXEModify(ProgName : PathStr; KeepDT : boolean; var Data;
N : word)
Result type integer
Remarks EXEModify modifies global variables (typed constants) in the
initialized data segment of the current EXE file. In DOS
versions 3.0 and up, EXEModify takes the program name from
ParamStr(0). In DOS versions below 3.0, EXEModify searches the
DOS path for the program passed in ProgName.
If KeepDT is true, then the original file date/time stamp is
preserved.
EXEModify cannot modify global variables that are declared but
not initialized (i.e. global variables that are not typed
constants) as these lie in the BSS segment of the program and
are not in fact in the EXE image file itself.
Return value EXEModify returns 1 if successful (data modified in EXE file),
0 if EXE file found but data item is not in the EXE file, and
-1 in case of file error (e.g. file not found). If the return
value is -1, check for a file error with IOResult.
}
function EXEModify(ProgName : PathStr; KeepDT : boolean; var Data; N : word) : integer;
var
_ProgName : PathStr; { Program name }
RetCode : integer; { Function return code }
OldFileMode : byte; { Old file open mode }
ProgFile : file; { Program file handle }
EXE : EXEHeader; { EXE file header }
NumRW : word; { Number of bytes read or written }
FileLen : longint; { Program file length }
DTStamp : longint; { Program date/time stamp }
SeekLen : longint; { Seek length into program file }
begin
if Lo(DOSVersion) < 3 then
{ Search path for program }
begin
_ProgName := FSearch(ProgName, GetEnv('PATH'));
if _ProgName <> '' then
_ProgName := FExpand(_ProgName);
end
else
{ Program name is 0th parameter in DOS versions 3.0 and up }
_ProgName := ParamStr(0);
{ Assume error }
RetCode := -1;
if _ProgName <> '' then
begin
{ Set file mode to allow reading and writing }
OldFileMode := FileMode;
FileMode := 2;
Assign(ProgFile, _ProgName);
Reset(ProgFile, 1);
FileMode := OldFileMode;
if InOutRes = 0 then
begin
BlockRead(ProgFile, EXE, EXEHSize, NumRW);
if (NumRW <> EXEHSize) or (EXE.ID <> EXEID) then
{ File does not have valid EXE file header so say file not found }
InOutRes := 2
else
begin
{ Cannot write beyond end of file }
FileLen := FileSize(ProgFile);
if KeepDT then
{ Save date/time stamp }
GetFTime(ProgFile, DTStamp);
RetCode := 0;
SeekLen := LongInt(Seg(Data) - (PrefixSeg + 16) + EXE.Size) shl 4 + LongInt(Ofs(Data));
if SeekLen + N <= FileLen then
begin
Seek(ProgFile, SeekLen);
if InOutRes = 0 then
begin
BlockWrite(ProgFile, Data, N, NumRW);
if (InOutRes = 0) and (NumRW = N) then
{ Seek and write was successful }
RetCode := 1
end
end;
if KeepDT then
{ Restore date/time stamp }
SetFTime(ProgFile, DTStamp)
end;
Close(ProgFile)
end
end
else
{ File not found }
InOutRes := 2;
EXEModify := RetCode
end;
end.